public class SingletonTest {
    public static void main(String[] args) {
        Singleton instance=Singleton.getInstance();
        Singleton instance2=Singleton.getInstance();
        System.out.println(instance==instance2);
    }
}

//饿汉式（静态变量）
class Singleton{
    //1.构造器私有化
    private Singleton(){

    }
    //2.本类内部创建对象实例
    private final static Singleton instance=new Singleton();
    //3.提供外部访问方法
    public static Singleton getInstance(){
        return instance;
    }
    /**
     * 可能造成内存浪费
     * 类加载的时候就完成了实例化，避免了线程同步
     */
}

//饿汉式（静态代码块）
class Singleton2{
    private Singleton2(){

    }

    private static Singleton2 instance;

    static {
        instance=new Singleton2();
    }

    public static Singleton2 getInstance(){
        return instance;
    }
}

//懒汉式=》不安全
class Singleton01{
    //1.构造器私有化
    private Singleton01(){

    }
    //2.本类内部创建对象实例
    private static Singleton01 instance;
    //3.提供一个静态方法，在使用到该方法的时候才去创建instance；
    //即烂汉式
    public static Singleton01 getInstance(){
        if (instance == null) {
            instance=new Singleton01();
        }
        return instance;
    }
    /**
     * 优点=用到才创建
     * 线程不安全==》实际开发不要用=》第一个线程if判断正确，准备去实例；第二个线程也判断正确
     */
}

//懒汉式=》安全，同步方法
class Singleton02{
    //1.构造器私有化
    private Singleton02(){

    }
    //2.本类内部创建对象实例
    private static Singleton02 instance;
    //3.提供一个静态方法，在使用到该方法的时候才去创建instance；
    //即烂汉式
    public static synchronized Singleton02 getInstance(){
        if (instance == null) {
                instance=new Singleton02();
        }
        return instance;
    }
    /**
     *
     */
}

//双重检查=》推荐
class Singleton3{
    //1.构造器私有化
    private Singleton3(){

    }
    //2.本类内部创建对象实例
    private static volatile Singleton3 instance;
    //3.提供一个静态方法，在使用到该方法的时候才去创建instance；
    //即饿汉式
    public static Singleton3 getInstance(){
        if (instance == null) {
            synchronized (Singleton3.class){
                instance=new Singleton3();
            }
        }
        return instance;
    }
    /**
     * 推荐
     */
}

//静态内部类

/**
 * 推荐
 * jvm装载类是线程安全的
 * 静态内部类调用方法时才被装在
 */
class Singleton4{
    private Singleton4(){

    }

    private static class SingletonInstance{
        private static final Singleton4 INSTANCE=new Singleton4();
    }


    public static Singleton4 getInstance(){
        return SingletonInstance.INSTANCE;
    }
}

/**
 * jdk=》java.lang.Runtime=>饿汉式
 * 使用场景：
 * 1.频繁创建销毁的对象2.工具类
 */